﻿// CCheckModelTreeCtrl.cpp: 实现文件
//

#include "stdafx.h"
#include "zChecker.h"
#include "CheckModelTreeCtrl.h"

#include "CheckModelEditDialog.h"

// CCheckModelTreeCtrl

IMPLEMENT_DYNAMIC(CCheckModelTreeCtrl, CTreeCtrl)

CCheckModelTreeCtrl::CCheckModelTreeCtrl()
{
	m_pModel = NULL;
	m_isEditable = FALSE;
}

CCheckModelTreeCtrl::~CCheckModelTreeCtrl()
{
	if (m_pModel)
	{
		m_pModel->Release();
		m_pModel = NULL;
	}
}


BEGIN_MESSAGE_MAP(CCheckModelTreeCtrl, CTreeCtrl)
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_NOTIFY_REFLECT(NM_RCLICK, &CCheckModelTreeCtrl::OnNMRClick)
	ON_COMMAND(IDR_RMENU_MODEL_TREE_EDITABLE, &CCheckModelTreeCtrl::OnRmenuModelTreeEditable)
	ON_UPDATE_COMMAND_UI(IDR_RMENU_MODEL_TREE_EDITABLE, &CCheckModelTreeCtrl::OnUpdateRmenuModelTreeEditable)
	ON_NOTIFY_REFLECT(NM_CLICK, &CCheckModelTreeCtrl::OnNMClick)
	ON_WM_CONTEXTMENU()
END_MESSAGE_MAP()



// CCheckModelTreeCtrl 消息处理程序




int CCheckModelTreeCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CTreeCtrl::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码

	return 0;
}


void CCheckModelTreeCtrl::OnSize(UINT nType, int cx, int cy)
{
	CTreeCtrl::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码
}

/**
 * 显示模型检查项
 * 1）在不可编辑(默认)下，只显示Model上已经挂载的检查项
 * 2）在可编辑状态下，显示质量元素库中的全部项。已经在Model上的检查项CheckBox设置为打钩状态
 * 3）通过设置CheckBox的状态来实现Model上挂载或卸载CheckItem
 */
void CCheckModelTreeCtrl::Populate(BOOL bIsShowAll)
{
	this->DeleteAllItems();
	this->InsertItem("检查模型", MODEL_TREE_ROOT_NODE, MODEL_TREE_ROOT_NODE, TVI_ROOT);
	HTREEITEM hRoot = this->GetRootItem();

	ck::ElementRepository* pRepository = ck::ElementRepository::GetInstance();
	ck::CheckElement* pElement = NULL;
	ck::EnumCheckElement* pElements = NULL;
	pElements = pRepository->GetElements();
	if (pElements)
	{
		pElements->Reset();
		while ((pElement = pElements->Next()))
		{
			const char* szName = pElement->GetName();
			z_uint32 code = pElement->GetCode();			

			HTREEITEM hItem = this->InsertItem(szName, MODEL_TREE_MODEL_NODE, MODEL_TREE_MODEL_NODE, hRoot);			
			this->SetItemData(hItem, (DWORD)code);

			if (PopulateSubElement(code, hItem, bIsShowAll))
			{
				//该模型有检查项，如果Tree处于可编辑状态，需要设置CheckBox
				if (m_isEditable)
				{
					this->SetCheck(hItem, TRUE);
				}
			}
			else
			{
				//如果没有子节点的话，需要将当前节点删除
				if(!bIsShowAll)
				{
					this->DeleteItem(hItem);
				}				
			}
		}
		pElements->Release();

		this->Expand(hRoot, TVE_EXPAND);
	}
}

BOOL CCheckModelTreeCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此添加专用代码和/或调用基类
	cs.style |= TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_HASBUTTONS | TVS_NOHSCROLL | TVS_EX_FADEINOUTEXPANDOS;

	return CTreeCtrl::PreCreateWindow(cs);
}

void CCheckModelTreeCtrl::AttachBitmap()
{
	CBitmap bmp;
	if (bmp.LoadBitmap(IDB_BITMAP_CHECK_MODEL_TREE_16))
	{
		m_il.Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 0);
		m_il.Add(&bmp, RGB(255, 0, 255));
		int nCount = m_il.GetImageCount();
		for (int i = 1; i < nCount; i++)         //support 16
		{
			m_il.SetOverlayImage(i, i);
		}
		SetImageList(&m_il, TVSIL_NORMAL);
	}
}

/************************************************************************/
/* TRUE	：如果PopulateAllSubElement添加了子节点                          */
/* FALSE：如果PopulateAllSubElement没有子节点                            */
/************************************************************************/
BOOL CCheckModelTreeCtrl::PopulateSubElement(z_uint32 nParentCode, HTREEITEM hParentItem, BOOL bIsShowAll)
{
	BOOL ret = FALSE;

	ck::ElementRepository* pRepository = ck::ElementRepository::GetInstance();
	ck::CheckElement* pElement = NULL;
	ck::EnumCheckElement* pElements = NULL;
	pElements = pRepository->GetChildElements(nParentCode);
	if (pElements)
	{
		pElements->Reset();
		while ((pElement = pElements->Next()))
		{
			const char* szName = pElement->GetName();
			z_uint32 code = pElement->GetCode();
			HTREEITEM hItem = this->InsertItem(szName, MODEL_TREE_SUBE_NODE, MODEL_TREE_SUBE_NODE, hParentItem);
			this->SetItemData(hItem, (DWORD)code);

			if(PopulateItem(code, hItem, bIsShowAll))
			{
				//该模型有检查项，如果Tree处于可编辑状态，需要设置CheckBox
				if (m_isEditable)
				{
					this->SetCheck(hItem, TRUE);
				}				
				ret = TRUE;
			}
			else
			{
				if (!bIsShowAll)
				{
					this->DeleteItem(hItem);
				}
			}

		}
		pElements->Release();

		this->Expand(hParentItem, TVE_EXPAND);
	}

	return ret;
}

BOOL CCheckModelTreeCtrl::PopulateItem(z_uint32 nParentCode, HTREEITEM hParentItem, BOOL bIsShowAll)
{
	BOOL ret = FALSE;

	ck::CheckModelManager* pModelManager = ck::CheckModelManager::GetInstance();

	ck::ElementRepository* pRepository = ck::ElementRepository::GetInstance();
	ck::CheckElement* pElement = NULL;
	ck::EnumCheckElement* pElements = NULL;
	pElements = pRepository->GetChildElements(nParentCode);

	if (pElements)
	{
		pElements->Reset();
		while ((pElement = pElements->Next()))
		{
			const char* szName = pElement->GetName();
			z_uint32 nItemCode = pElement->GetCode();
			z_uint32 nModelCode = m_pModel->GetID();

			if (pModelManager->HasItem(nModelCode, nItemCode))
			{
				ret = TRUE;
				HTREEITEM hItem = this->InsertItem(szName, MODEL_TREE_ITEM_NODE, MODEL_TREE_ITEM_NODE, hParentItem);
				this->SetItemData(hItem, (DWORD)nItemCode);

				if (m_isEditable)
				{
					this->SetCheck(hItem, TRUE);
				}
			}
			else
			{
				if (bIsShowAll)
				{
					//如果全部显示的话，需要把其他的CheckItem也添加到Tree上
					HTREEITEM hItem = this->InsertItem(szName, MODEL_TREE_ITEM_NODE, MODEL_TREE_ITEM_NODE, hParentItem);
					this->SetItemData(hItem, (DWORD)nItemCode);
				}
			}

		}
		pElements->Release();

		this->Expand(hParentItem, TVE_EXPAND);
	}

	return ret;
}

//#define		MODEL_TREE_ROOT_NODE	0
//#define		MODEL_TREE_MODEL_NODE	1
//#define		MODEL_TREE_SUBE_NODE	2
//#define		MODEL_TREE_ITEM_NODE	3
int	CCheckModelTreeCtrl::GetNodeType(HTREEITEM hItem)
{
	int nType = -1;
	HTREEITEM hRoot = GetRootItem();

	if (hRoot == hItem)
	{
		return MODEL_TREE_ROOT_NODE;
	}
	else
	{
		HTREEITEM hParent = GetParentItem(hItem);
		if (hParent == hRoot)
		{
			return MODEL_TREE_MODEL_NODE;
		}
		else
		{
			hItem = hParent;
			hParent = GetParentItem(hItem);
			if (hParent == hRoot)
			{
				return MODEL_TREE_SUBE_NODE;
			}
			else
			{
				hItem = hParent;
				hParent = GetParentItem(hItem);
				if (hParent == hRoot)
				{
					return MODEL_TREE_ITEM_NODE;
				}
				else
				{
					hItem = hParent;
					hParent = GetParentItem(hItem);
					if (hParent == hRoot)
					{
						return MODEL_TREE_OPER_NODE;
					}
				}
			}
			
		}
	}

	return nType;
}


void CCheckModelTreeCtrl::SetModel(ck::CheckModel* pModel)
{
	if (m_pModel)
	{
		m_pModel->Release();
		m_pModel = NULL;
	}
	m_pModel = pModel;
	if (m_pModel)
	{
		m_pModel->AddRef();
	}
}

void CCheckModelTreeCtrl::OnNMRClick(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: 在此添加控件通知处理程序代码

	CPoint pt, spt;
	if (!GetCursorPos(&pt))
	{
		return;
	}
	spt = pt;
	ScreenToClient(&pt);
	UINT uFlag = 0;
	HTREEITEM hItem = HitTest(pt, &uFlag);
	if ((NULL == hItem) || !(TVHT_ONITEM&uFlag))
	{
		return;
	}
	SelectItem(hItem);

	//在的编辑框内显示当前的Item
	int nNodeType = GetNodeType(hItem);
	switch (nNodeType)
	{
	case MODEL_TREE_ROOT_NODE:
	{
		CMenu m, *mn;
		m.LoadMenu(IDR_RMENU_MODEL_TREE_ROOT_NODE);//加载菜单资源
		mn = m.GetSubMenu(0);//获取菜单子项
		CMenu* pSubMenu = mn->GetSubMenu(0);
		mn->CheckMenuItem(IDR_RMENU_MODEL_TREE_EDITABLE, m_isEditable ? MF_CHECKED : MF_UNCHECKED); 
		//mn->ModifyMenu(IDR_RMENU_MODEL_TREE_EDITABLE - 1, MF_BYPOSITION, 0, m_isEditable ? "结束编辑" : "启用编辑");
		//AfxGetMainWnd()->Invalidate();
		mn->TrackPopupMenu(TPM_LEFTALIGN, spt.x, spt.y, this);    //显示菜单
	}
	break;
	case MODEL_TREE_MODEL_NODE:
	{

	}
	break;
	case MODEL_TREE_SUBE_NODE:
	{

	}
	break;
	case MODEL_TREE_ITEM_NODE:
	{
		//在编辑框中显示检查项

	}
	break;
	case MODEL_TREE_OPER_NODE:
	{

	}
	break;
	}

	*pResult = 0;
}


void CCheckModelTreeCtrl::OnRmenuModelTreeEditable()
{
	// TODO: 在此添加命令处理程序代码
	m_isEditable = !m_isEditable;
	if (m_isEditable)
	{
		this->ModifyStyle(0, TVS_CHECKBOXES);
		//PopulateAll();
		Populate(TRUE);
	}
	else
	{
		this->ModifyStyle(TVS_CHECKBOXES,0);
		Populate(FALSE);
	}
}


void CCheckModelTreeCtrl::OnUpdateRmenuModelTreeEditable(CCmdUI *pCmdUI)
{
	// TODO: 在此添加命令更新用户界面处理程序代码
	pCmdUI->SetCheck(m_isEditable);
}


void CCheckModelTreeCtrl::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	CPoint pt;
	if (!GetCursorPos(&pt))
	{
		return;
	}

	this->ScreenToClient(&pt);
	UINT uFlag = 0;
	HTREEITEM hItem = this->HitTest(pt, &uFlag);
	if ((NULL == hItem) || !(TVHT_ONITEM&uFlag))
	{
		return;
	}
	this->SelectItem(hItem);

	CCheckModelEditDialog* pDialog = (CCheckModelEditDialog*)GetParent();

	//在的编辑框内显示当前的Item
	int nNodeType = this->GetNodeType(hItem);
	if (nNodeType == MODEL_TREE_ITEM_NODE)
	{
		CString strText = this->GetItemText(hItem);
		pDialog->UpdateCheckElementText(strText);
		
	}

	if (TVHT_ONITEMICON&uFlag)
	{	//点击图标
		//AfxMessageBox("CheckBOx");
	}
	else if (TVHT_ONITEMBUTTON&uFlag)
	{	//点击按钮
		//AfxMessageBox("CheckButton");
	}
	else if (TVHT_ONITEMSTATEICON&uFlag)
	{	//点击CheckBox
		OnCheckBoxClicked(hItem);
	}
	else if (TVHT_ONITEMLABEL&uFlag)
	{	//点击节点本身
		OnLabelClicked(hItem);
	}

	*pResult = 0;
}



void CCheckModelTreeCtrl::OnCheckBoxClicked(HTREEITEM hItem)
{
	int nNodeType = this->GetNodeType(hItem);
	switch (nNodeType)
	{
	//case MODEL_TREE_ROOT_NODE:
	//{

	//}
	//break;
	//case MODEL_TREE_MODEL_NODE:
	//{

	//}
	//break;
	//case MODEL_TREE_SUBE_NODE:
	//{

	//}
		//break;
	case MODEL_TREE_ITEM_NODE:
	{
		//在编辑框中显示检查项		
		z_uint32 nModID = m_pModel->GetID();
		z_uint32 nItemID = this->GetItemData(hItem);
		
		BOOL checked = !this->GetCheck(hItem);
		if (checked)
		{
			//添加检查项
			ck::CheckModelManager* pModelManager = ck::CheckModelManager::GetInstance();
			RESULTCODE rc = pModelManager->AddItem(nModID, nItemID);
			if (rc == RC_SUCCESS)
			{
				//更新上一级节点的Check状态
				this->SetCheck(GetParentItem(hItem), TRUE);
				this->SetCheck(GetParentItem(GetParentItem(hItem)), TRUE);
				this->SetCheck(GetParentItem(GetParentItem(GetParentItem(hItem))), TRUE);
			}
			else
			{
				AfxMessageBox("添加检查项失败");
			}
		}
		else
		{
			//删除检查项
			ck::CheckModelManager* pModelManager = ck::CheckModelManager::GetInstance();
			RESULTCODE rc = pModelManager->RemoveItem(nModID, nItemID);
			if (rc != RC_SUCCESS)
			{
				AfxMessageBox("删除节点失败");
			}
		}

	}
	break;
	//case MODEL_TREE_OPER_NODE:
	//{

	//}
	//break;
	default:
	{
		//设置除了CheckItem节点外的其他节点均为不可编辑状态
		BOOL checked = !this->GetCheck(hItem);
		this->SetCheck(hItem, checked);
	}
	break;
	}
}



void CCheckModelTreeCtrl::OnLabelClicked(HTREEITEM hItem)
{
	int nNodeType = this->GetNodeType(hItem);
	switch (nNodeType)
	{
		//case MODEL_TREE_ROOT_NODE:
		//{

		//}
		//break;
		//case MODEL_TREE_MODEL_NODE:
		//{

		//}
		//break;
		//case MODEL_TREE_SUBE_NODE:
		//{

		//}
			//break;
	case MODEL_TREE_ITEM_NODE:
	{
		//在编辑框中显示检查项

		z_uint32 code = (z_uint32)(this->GetItemData(hItem));
		ck::ElementRepository* pRepository = ck::ElementRepository::GetInstance();

		ck::CheckItem* pCheckItem = (ck::CheckItem*)pRepository->GetElementByCode(code);
		if (pCheckItem)
		{
			CCheckModelEditDialog* pDialog = (CCheckModelEditDialog*)GetParent();
			pDialog->UpdateCheckItemGrid(pCheckItem);
			pDialog->PopulateOperators(pCheckItem);
		}
	}
	break;
	//case MODEL_TREE_OPER_NODE:
	//{

	//}
	//break;
	default:
	{
		//设置除了CheckItem节点外的其他节点均为不可编辑状态
		BOOL checked = !this->GetCheck(hItem);
		this->SetCheck(hItem, checked);
	}
	break;
	}
}


void CCheckModelTreeCtrl::OnContextMenu(CWnd* /*pWnd*/, CPoint /*point*/)
{
	// TODO: 在此处添加消息处理程序代码
}
